In recent years, Java has begun to be used widely as application software in the embedded use of a microprocessor. This is because of excellent program transportability which allows a Java program to run on a machine provided with the JVM (Java Virtual Machine) implemented thereon in the form of hardware or software, irrespective of the type of a processor or the configuration of a system. A Java program has the advantage that an object code is small in size since the program is based on stack operations and a program instruction, which is termed “bytecode” in Java, does not need an operand field. The Java program also has the advantage of being excellent in security since the concept on data formats is strict and the verification of a bytecode is performed before the execution of the program.
Most of embedded systems using Java implement a JVM function by using software. This is because a Java program can be executed on the same processor as software other than Java, e.g., a multimedia application program such as OS or MPEG4. In the case where a Java program is executed under a JVM environment implemented by using software, however, a problem is encountered that the program execution speed is extremely slow compared with the case of executing a program in which the same contents of processing are described in native instructions of a processor. If a comparison is made between the case where, e.g., a Dhrystone benchmark program is described in the C language, compiled, and executed and the case where the program is described in Java and executed on the JVM, a several tens of times performance difference is present therebetween. The following is the two major factors causing the performance difference.
(1) Since Java instructions (bytecodes) are executed by an interpreter on the JVM, an interpreter overhead occurs.
(2) Since a Java execution model assumes arithmetic operations on a stack, frequent memory accesses are necessarily entailed when a Java program is executed on an ordinary register-based processor so that an ALU needs extra execution cycles.
As conventional technologies for executing a Java program at a high speed, the JIT (Just In Complier) composed of software and an accelerator composed of hardware are known. However, most of embedded uses with limited memory capacity tend to adopt a hardware accelerator since the JIT requires a large memory capacity.
As hardware accelerators, various models including a dedicated processor type and a type having an accelerator function embedded in a part of an existing processor have been proposed. Examples of the accelerator of the latter type include the Jazelle available from ARM Limited and the JSTAR available from Nazomi communications, Inc.
For example, in a document “Java to Go: Part 1, Microprocessor Report, Feb. 12, 2001” and in “Java Virtual Machine Hardware for RISC and CISC Processors” disclosed in International Publication No. WO 00/34844 (PCT/US99/28782), a program execution speed is increased by converting bytecodes read out from an instruction cache to native instructions of a processor by using a hardware translator and thereby reducing the interpreter overhead, which is the factor (1).
As schematically shown in, e.g., FIG. 6, the JVM includes, as areas referenced by an interpreter 90, a class data area 80 in which bytecode sequences 81 and constant pools 82 are defined, an instance data area 83 in which array objects 84 and fields 85 such as instance variables are defined, and frame stacks 86. Each of the frame stacks 86 is composed of a plurality of frames 87 each consisting of an operand stack 88 and a local variable area 89. Variables used for arithmetic operations on the JVM are basically defined in the local variable areas 89 in the individual frame stacks 86. The interpreter 90 of the JVM successively reads out bytecodes from the bytecode sequence 81 and converts a Java instruction shown by each of the bytecodes to a native instruction format of the processor 91. In FIG. 6, representative examples of Java instructions are shown inside the parentheses in correspondence with the individual areas described above.
In a Java program, the operation of loading those of the variables defined in the local variable area 89 which are necessary for the arithmetic operation on the stack top of the operand stack 88 is performed prior to each arithmetic operation. This operation is performed by a load instruction (e.g., “iload”) specified by a bytecode. After an operand necessary for the arithmetic operation is stacked on the operand stack 88, an arithmetic instruction specifying the stack top mentioned above as an implicit operand is issued. By the arithmetic instruction, an arithmetic operation using the contents of the stack top as an operand is executed and the result of the arithmetic operation is stored temporarily on the stack top of the operand stack 88. The result of the arithmetic operation should finally be stored in the local variable area 89 in the frame stack and the storing of the result of the arithmetic operation is implemented by a store instruction (e.g., “istore”) indicated by the next bytecode.
Thus, under a JVM execution environment, the operation of moving local variables onto the stack top and moving the result of the arithmetic operation from the stack top to the local variable area occurs on each arithmetic operation. Accordingly, in the case where a Java program is executed on an ordinary processor using a general register as an operand area, frequent accesses to the general register occur.
In International Publication No. WO 00/34844 (PCT/US99/28782) mentioned above, for example, the R0 to R5 of general registers are mapped to the higher-order six regions of the operand stack and the R6 and R7 thereof are mapped for local variables. In the document “Java to Go: Part 1, Microprocessor Report, Feb. 12, 2001”, on the other hand, the R0 to R3 of general registers are mapped to the higher-order four regions of the operand stack and a 0-th local variable is mapped to the R4 thereof, as stated in page 3.
Thus, in these prior-art technologies, the mapping of both of the operand stack and the local variables to the general registers is fixed so that the use of the general registers is lacking in flexibility and the use efficiency of the general registers are lowered thereby. In addition, these prior-art technologies faithfully execute all the Java instructions specified by the bytecode sequence by using register-based processors and no consideration has been given to the avoidance of extra execution cycles pointed out as the factor (2) causing the delayed execution of a Java program.
It is therefore an object of the present invention to provide a processor system which executes a Java program at a higher speed by omitting redundant instruction execution cycles.
Another object of the present invention is to provide a processor system provided with a Java accelerator capable of flexibly controlling the mapping of an operand stack and local variables to a general register.